遗传算法(初步)

试求函数:x + 10 * sin(5 * x) + 7 * cos(4 * x)在0到9之间的最大值。

如何通俗易懂地解释遗传算法?有什么例子? - 赵志强的回答 - 知乎https://www.zhihu.com/question/23293449/answer/120102627

题目和一些解释就在上面,下面直接给出代码。

//遗传算法
#include "iostream"
#include "algorithm"
#include "vector"
#include "random"
#include "iterator"
#include "bitset"
#define MAX_COUNT 200
#define GENE_BIT 17
#define Group_Scale 50
#define CROSSOVER_PERCENT 0.6
#define MUTATION_PERCENT 0.1
using namespace std;


static default_random_engine e;//随机数生成引擎
double fitness_function(double x)//求此函数的最大值
{
	//return x*x*sin(3 * x)*cos(2 * x);
	//return -x*(x - 1);//适应函数
	return x + 10 * sin(5 * x) + 7 * cos(4 * x);
}

class One
{
public:
	bitset<GENE_BIT> chromosome;//基因位数为GENE_BIT的染色体

};

class Group
{
public:
	Group(int a)
	{
		num = a;
		group.resize(a);
		percent.resize(a);
	}
	int num = Group_Scale;//种群里个体的数量
	vector<One> group;
	vector<double> percent;
	void Selection();
	void CrossOver();
	void Mutation();
};

void Group::Mutation()
{
	static uniform_real_distribution<double> rand_mutation(0, 1);
	static uniform_int_distribution<int> rand_point_M(0, GENE_BIT-1);
	for (int i = 0; i < group.size(); i++)
	{
		if (rand_mutation(e) <= MUTATION_PERCENT)
		{
			int point = rand_point_M(e);//变异的位置
			group[i].chromosome[point].flip();//该点取反
			//cout << "变异一次" << endl;
		}
	}

}


void Group::CrossOver()
{
	static uniform_real_distribution<double> rand_cross(0, 1);
	static uniform_int_distribution<int> rand_point(0, GENE_BIT-1);
	for (size_t i = 0; i < group.size(); i+=2)
	{
		if (rand_cross(e) <= CROSSOVER_PERCENT)
		{
			//int point = rand_point(e);//单点交叉
			bitset<GENE_BIT> tmp = group[i].chromosome;
			for (int point = rand_point(e); point < GENE_BIT; point++)
			{
				tmp[point] = group[i + 1].chromosome[point];
				group[i + 1].chromosome[point] = group[i].chromosome[point];
			}
			group[i].chromosome = tmp;
		}
	}
}


void Group::Selection()//选择函数
{
	static uniform_real_distribution<double> rand_0_1(0, 1);//随机数生成范围
	//group.resize(num);
	//percent.resize(num);
	double sum = 0;
	vector<One> new_group(group);
	for (size_t i = 0; i < group.size(); i++)
	{
		sum += fitness_function((double)group[i].chromosome.to_ulong()/10000);
	}
	for (int i = 0; i < group.size(); i++)
	{
		percent[i] = fitness_function((double)group[i].chromosome.to_ulong() / 10000) / sum;
	//计算每一份的概率
	}
	double rate = 0;
	int j = 0;
	vector<double> per(percent);
	for (int k = 0; k < group.size(); k++)//k次选择
	{
		int i = 0;
		per = percent;
		rate = rand_0_1(e);
		while (rate > per[i])
		{
			per[i+1] += per[i];
			i++;
		}			
		new_group[j] = group[i];
		j++;
	}
	group = new_group;//将新总群放入
}

int main()
{
	static uniform_real_distribution<double> u(0, 9);//随机数生成范围	
	Group g(Group_Scale);//有Group_Scale个个体
	for (int i = 0; i < Group_Scale; i++)
	{
		g.group[i].chromosome = u(e) * 10000;//将double转化成0到90000中的某个数
		//cout << g.group[i].chromosome.to_ulong() << endl;
	}//基因初始化
	
	for (int i = 0; i < MAX_COUNT; i++)
	{
		g.Selection();//选择
		g.CrossOver();//交配
		g.Mutation();//变异
	}
	for (int i = 0; i < Group_Scale; i++)
	{
		cout << fitness_function((double)g.group[i].chromosome.to_ulong()/10000)<<endl;
	}
	while (1);
	return 0;
}


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值